import React, { useState, useEffect } from 'react';
import { Radio, message, Spin, Select, TreeSelect } from 'antd';
import { toArray } from '@/utils/utils';
import { size, isObject, hasIn, uniqBy } from 'lodash';
import { fetchApproveConfig, fetchOrgByUrl } from '../../../../services';

const { Option } = Select;

/**
 *
 * 注意: 这个组件是根据后端动态配置来的，和后端有很强的耦合性
 *
 * */

// 流程设计选择人员、部门等组件
const Organization = ({
    defaultValue = undefined,
    defaultType,
    onChange,
    organizationCode = 100,
    className,
    bData = {},
    ...restProps
}) => {
    const [configData, setConfigData] = useState(null);
    const [loading, setLoading] = useState(false);
    const [orgType, setOrgType] = useState(defaultType || null);
    const [typeChangeLoading, setTypeChangeLoading] = useState(false);
    const [isShowTree, setIsShowTree] = useState(undefined);

    const [selectValue, setSelectValue] = useState();

    const [expandedKeys, setExpandedKeys] = useState([]);
    // 联系人、组织机构（部门）控件数组
    const drawingItems = JSON.parse(localStorage.getItem('drawingItems') || '[]');
    const contactsInputs = [];
    drawingItems.forEach(item => {
        if ((item?.tag === 'ContactsInput' || item?.tag === 'FunctionalTree') && item?.rules[0]?.required) {
            contactsInputs.push(item);
        }
        if (item?.children && item?.children.length > 0) {
            item.children.forEach(subitem => {
                if (
                    (subitem?.tag === 'ContactsInput' || subitem?.tag === 'FunctionalTree') &&
                    subitem?.rules && subitem?.rules[0]?.required
                ) {
                    contactsInputs.push(subitem);
                }
            });
        }
    });

    // 通过url请求返回的动态属性、数据
    const [dynamicData, setDynamicData] = useState({});

    const getTypeData = async value => {
        const { url, key, keyValue, nameValue, showTreeFlag } = configData[value];
        setIsShowTree(showTreeFlag);
        // 清除动态属性和数据
        setDynamicData({});
        setTypeChangeLoading(true);
        const { code, data, msg } = await fetchOrgByUrl({
            url,
            organizationCode
        });
        if (code === 10000) {
            setDynamicData({
                keyValue,
                nameValue,
                candidateUsers: key,
                orgData: data
            });
        } else {
            message.error(msg);
        }
        setTypeChangeLoading(false);
    };
    // tree数据格式化
    const getTreeData = data =>
        data.map(item => ({
            ...item,
            value: item.organizationCode,
            title: item.organizationName,
            key: item.organizationCode,
            selectable: !(item.organizationType === 1 || item.organizationType === 2),
            disableCheckbox: !!(item.organizationType === 1 || item.organizationType === 2),
            children: item.children ? getTreeData(item.children) : item.children
        }));
    // 岗位数据格式化
    const filterDuties = tree =>
        tree.map(i => ({
            title: i.dutyAlias,
            value: i.dutyCode,
            key: i.dutyCode
        }));

    // 机构数据格式化
    const filterTree = tree =>
        tree.map(
            ({
                children,
                organizationName,
                organizationCode: treeOrganizationCode,
                organizationType,
                duties,
                ...props
            }) => {
                if ((children && children.length > 0) || (duties && duties.length > 0)) {
                    return {
                        children: [...filterTree(children), ...filterDuties(duties)],
                        title: organizationName,
                        value: treeOrganizationCode,
                        key: treeOrganizationCode,
                        disabled: false,
                        selectable: false,
                        organizationType,
                        ...props
                    };
                }
                return {
                    children: '',
                    title: organizationName,
                    value: treeOrganizationCode,
                    key: treeOrganizationCode,
                    disabled: !!(!children?.length && !duties?.length),
                    selectable: false, // 不是岗位的都为false
                    organizationType,
                    ...props
                };
            }
        );
    // 岗位、机构数据格式化
    const getTreeProData = tree => {
        const result = filterTree(tree);
        return result;
    };
    // 获取基础配置信息
    const getConfigData = async () => {
        setLoading(true);
        const { data, code, msg } = await fetchApproveConfig();
        if (code === 10000) {
            setConfigData({ ...data });
        } else {
            setConfigData(null);
            message.error(msg);
        }
        setLoading(false);
    };

    // 组件初始化
    useEffect(() => {
        getConfigData();
    }, []);

    // 数据回填 isShowTree 1 为 树形， 2 为岗位
    useEffect(() => {
        let tempValue = defaultValue;
        let tempExpandedKeys = toArray(defaultValue);
        if (size(defaultValue) > 0) {
            if (isShowTree === 1 || isShowTree === 2) {
                if (Array.isArray(defaultValue)) {
                    if (!isObject(defaultValue)) {
                        tempValue = defaultValue.map(item => item.value);
                    }
                    tempExpandedKeys = defaultValue.map(item => item.value);
                }
            }
        }
        setExpandedKeys(tempExpandedKeys);
        setSelectValue(size(tempValue) > 0 ? tempValue : undefined);
    }, [defaultValue, isShowTree]);

    useEffect(() => {
        if (defaultType && configData && configData[defaultType] && configData[defaultType].url !== '') {
            getTypeData(defaultType);
        }
        const { optionalType } = bData;
        // 联系人动态值
        if (optionalType === 'form') {
            setDynamicData({
                keyValue: 'formId',
                nameValue: 'label',
                candidateUsers: bData.candidateUsers,
                orgData: contactsInputs
            });
        }
    }, [configData]);

    const getChildrenData = datasource => {
        if (size(datasource) > 0) {
            const tempArr = [];
            // 递归获取数据
            const deepFn = node => {
                let obj = node;
                if (hasIn(obj, 'props')) {
                    obj = obj.props;
                }
                tempArr.push({ value: obj?.value, label: obj?.title });
                if (Array.isArray(obj.children)) {
                    obj.children.forEach(item => {
                        deepFn(item);
                    });
                }
            };
            deepFn(datasource);
            return tempArr;
        }
        return [];
    };
    // 渲染 审批人
    const renderTemp = () => {
        // showTreeFlag  1 为树形  2为 岗位 默认下拉选择
        if (isShowTree === 1) {
            return (
                <>
                    {dynamicData.orgData && dynamicData.orgData.length > 0 && (
                        <TreeSelect
                            showSearch
                            placeholder="请选择"
                            value={selectValue}
                            treeCheckable={configData[orgType].selectMode}
                            treeDefaultExpandedKeys={expandedKeys}
                            treeData={getTreeData(dynamicData.orgData)}
                            style={{ width: '100%' }}
                            dropdownStyle={{ maxHeight: 300 }}
                            maxTagCount={5}
                            allowClear
                            labelInValue
                            treeCheckStrictly
                            treeNodeFilterProp="title"
                            onChange={(e = [], label, extra) => {
                                const selectKeys = [];
                                const selectLabels = [];
                                let tempArr = Array.isArray(e) ? e : [e];
                                const maxSelect = 20;

                                if (extra.checked === true) {
                                    tempArr = getChildrenData(extra.triggerNode.props);
                                    tempArr = uniqBy([...e, ...tempArr], 'value');
                                }
                                tempArr.forEach(item => {
                                    selectKeys.push(item.value);
                                    selectLabels.push(item.label);
                                });
                                if (tempArr.length > maxSelect) {
                                    message.warn(`最多选择${maxSelect}个`);
                                    tempArr = tempArr.slice(0, maxSelect);
                                }
                                onChange({
                                    orgType, // 类型的值
                                    orgValue: tempArr, // 下拉列表的值
                                    // 没url的时候是type的文本，如果有的话是下拉列表选中值文本。节点回显用
                                    orgLabel: selectLabels.join('，'),
                                    // 给后端的节点字段
                                    candidateUsers: dynamicData.candidateUsers.replace(
                                        '*',
                                        dynamicData.candidateUsers.includes('_')
                                            ? selectKeys.join('__')
                                            : selectKeys.join(',')
                                    ),
                                    optionalType: dynamicData.optionalType, // 联系人标识
                                    typeText: configData[orgType].name // 类型文本
                                });
                            }}
                        />
                    )}
                </>
            );
        }
        if (isShowTree === 2) {
            return (
                <>
                    {dynamicData.orgData && dynamicData.orgData.length > 0 && (
                        <TreeSelect
                            showSearch
                            treeNodeFilterProp="title"
                            treeCheckable={configData[orgType].selectMode}
                            treeData={getTreeProData(dynamicData.orgData)}
                            style={{ width: '100%' }}
                            dropdownStyle={{ maxHeight: 300 }}
                            maxTagCount={5}
                            allowClear
                            value={selectValue}
                            placeholder="请选择"
                            treeDefaultExpandedKeys={expandedKeys}
                            onChange={(e = [], label) => {
                                const selectLabels = label;
                                let arr = Array.isArray(e) ? e : [e];

                                const selectKeys = arr;
                                const maxSelect = 20;
                                if (arr.length > maxSelect) {
                                    message.warn(`最多选择${maxSelect}个`);
                                    arr = arr.slice(0, maxSelect);
                                }

                                onChange({
                                    orgType, // 类型的值
                                    orgValue: arr, // 下拉列表的值
                                    // 没url的时候是type的文本，如果有的话是下拉列表选中值文本。节点回显用
                                    orgLabel: selectLabels.join('，'),
                                    // 给后端的节点字段
                                    candidateUsers: dynamicData.candidateUsers.replace(
                                        '*',
                                        dynamicData.candidateUsers.includes('_')
                                            ? selectKeys.join('__')
                                            : selectKeys.join(',')
                                    ),
                                    optionalType: dynamicData.optionalType, // 联系人标识
                                    typeText: configData[orgType].name // 类型文本
                                });
                            }}
                        />
                    )}
                </>
            );
        }
        return (
            <>
                {dynamicData.orgData && (
                    <Select
                        value={defaultValue}
                        allowClear
                        labelInValue
                        mode={configData[orgType].selectMode}
                        showSearch
                        placeholder="请选择"
                        filterOption={(input, option) =>
                            option.props.children?.toLowerCase().indexOf(input?.toLowerCase()) >= 0
                        }
                        onChange={(e = []) => {
                            const selectKeys = [];
                            const selectLabels = [];
                            let arr = Array.isArray(e) ? e : [e];
                            const maxSelect = 20;
                            if (arr.length > maxSelect) {
                                message.warn(`最多选择${maxSelect}个`);
                                arr = arr.slice(0, maxSelect);
                            }

                            arr.forEach(item => {
                                selectKeys.push(item.key);
                                selectLabels.push(item.label);
                            });

                            let tempCandidateUsers = configData[orgType]?.key;
                            if (arr.length > 0) {
                                tempCandidateUsers = dynamicData.candidateUsers.replace(
                                    '*',
                                    dynamicData.candidateUsers.includes('_')
                                        ? selectKeys.join('__')
                                        : selectKeys.join(',')
                                );
                            }

                            onChange({
                                orgType, // 类型的值
                                orgValue: arr, // 下拉列表的值
                                // 没url的时候是type的文本，如果有的话是下拉列表选中值文本。节点回显用
                                orgLabel: selectLabels.join('，'),
                                // 给后端的节点字段
                                candidateUsers: tempCandidateUsers,
                                optionalType: dynamicData.optionalType, // 联系人标识
                                typeText: configData[orgType].name // 类型文本
                            });
                        }}
                        {...restProps}
                        style={{ margin: '0 auto 16px' }}
                    >
                        {dynamicData?.orgData?.map(item => (
                            <Option value={item[dynamicData.keyValue]} key={item[dynamicData.keyValue]}>
                                {item[dynamicData.nameValue]}
                            </Option>
                        ))}
                    </Select>
                )}
            </>
        );
    };
    return (
        <div className={className}>
            <Spin spinning={loading}>
                {configData && (
                    <div>
                        <Radio.Group
                            defaultValue={orgType}
                            style={{ lineHeight: '32px' }}
                            onChange={e => {
                                const { value } = e.target;
                                const { url, key, name, optionalType, showTreeFlag } = configData[value];

                                onChange({
                                    orgType: value, // 类型的值
                                    orgValue: [], // 下拉列表的值
                                    orgLabel: [name], // 没url的时候是type的文本，如果有的话是下拉列表选中值文本。节点回显用
                                    candidateUsers: key, // 给后端的节点字段
                                    url,
                                    showTreeFlag,
                                    typeText: configData[value].name // 类型文本
                                });
                                setIsShowTree(showTreeFlag);
                                // 有url去拉取数据
                                if (url !== '') {
                                    setOrgType(value);
                                    getTypeData(value);
                                } else {
                                    setDynamicData({});

                                    // 联系人
                                    if (optionalType === 'form') {
                                        setOrgType(value);
                                        setDynamicData({
                                            keyValue: 'formId',
                                            nameValue: 'label',
                                            candidateUsers: key,
                                            orgData: contactsInputs,
                                            optionalType
                                        });
                                    }
                                }
                            }}
                        >
                            {Object.keys(configData).map(
                                item =>
                                    configData[item].type.split(',').includes('1') && (
                                        <Radio
                                            style={{ padding: '0 6px', width: 150, marginBottom: 16 }}
                                            value={item}
                                            key={item}
                                        >
                                            {configData[item].name}
                                        </Radio>
                                    )
                            )}
                        </Radio.Group>
                        <Spin spinning={typeChangeLoading}>
                            {/* 有url请求的下拉 */}
                            {renderTemp()}
                        </Spin>
                    </div>
                )}
            </Spin>
        </div>
    );
};

export default Organization;
